package com.oa.tools.utils;

import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.Element;

public class SysConfig {

	private static Map<String,Map<String,Object>> userProps;
	private final static String defaultType = "系统设置";
	public static String ekpUser;
	public static String ekpPass;
	public static String domainName;
	public static String kkConsoleUser = "admin";
	public static String kkConsolePass = "kk20171110!";
	public static String jobCron = "";
	public static List<String> confText;
	private static String confPath = "config-default.xml";
	private static Document document;
	
	/**
	 * 加载配置文件
	 * @throws Exception
	 */
	public static void freshInit() throws Exception {
		userProps = new HashMap<String,Map<String,Object>>();
		
		confText = FileUtil.readTxt2List(confPath, "utf-8");
		
		document = XmlUtil.readXml(confPath);
		Element config = document.getRootElement();
		List<Element> propertiesList= config.elements();
		for(Element properties :propertiesList) {
			if("properties".equals(properties.getName())) {
				String propertiesName = properties.attributeValue("name");
				
				List<Element> propertyList= properties.elements();
				for(Element property :propertyList) {	
					if("property".equals(property.getName())) {
						String propName = property.attributeValue("name");
						
						Map<String,Object> valMap = userProps.get(propertiesName);
						if(valMap==null) {
							valMap=new HashMap<String,Object>();
							userProps.put(propertiesName, valMap);
						}
						
						if("set".equals(property.attributeValue("type"))) {
							List<Element> options= property.elements();
							for(Element option :options) {
								if("option".equals(option.getName())) {
									String optionVal = option.attributeValue("value");
									Set<String> optionSet=(Set<String>) valMap.get(propName);
									if(optionSet==null) {
										optionSet = new HashSet<>();
										valMap.put(propName, optionSet);
									}
									optionSet.add(optionVal);
								}
							}
							
						}else if("map".equals(property.attributeValue("type"))) {
							List<Element> options= property.elements();
							for(Element option :options) {
								if("option".equals(option.getName())) {
									String optionName = option.attributeValue("name");
									String optionVal = option.attributeValue("value");
									Map<String,String> optionMap=(Map<String,String>) valMap.get(propName);
									if(optionMap==null) {
										optionMap = new HashMap<String,String>();
										valMap.put(propName, optionMap);
									}
									optionMap.put(optionName,optionVal);
								}
							}
							
						}else {
							valMap.put(propName, property.attributeValue("value"));
						}
						
					}
				}
			}
			
		}
		
		ekpUser = getSysString("OA账号");
		ekpPass = getSysString("OA密码");
		domainName = getSysString("oa_domainName");
		kkConsoleUser = getSysString("KK后台用户");
		kkConsolePass = getSysString("KK后台密码");
		jobCron = getSysString("定时表达式");
		  
	}
	
	public static List<String> getConfText(){
		return confText;
	}
	
	/**
	 * 覆盖修改配置文本
	 * @param content
	 * @throws Exception
	 */
	public static void setConfText(String content) throws Exception{
		FileUtil.writeTxt2File(content, confPath,Charset.forName("UTF-8"),false);
		freshInit();
	}
	
	public static String getOutPath() {
		String dateStr = DateUtil.date2Str(new Date(), "yyyyMMdd_HHmmss");
		String outPath = String.valueOf(getSysString("正常日志文件")).replaceAll("\\.", dateStr + ".");
		return outPath;
	}

	public static String getRecordPath() {
		String path = String.valueOf(getSysString("流程处理记录路径"));
		return path;
	}

	static {
		try {
			freshInit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取字符串类型配置值
	 * @param type
	 * @param name
	 * @return
	 */
	public static String getString(String type, String name) {
		Map<String,Object> valMap = userProps.get(type);
		if(valMap==null) {
			return null;
		}
		String val =  (String) valMap.get(name);
		
		return val;
	}
	
	public static String getSysString(String name) {
		return getString(defaultType,name);
	}
	
	public static Set<String> getSet(String type, String name) {
		Map<String,Object> valMap = userProps.get(type);
		if(valMap==null) {
			return null;
		}
		Set<String> val =  (Set<String>) valMap.get(name);
		
		return val;
	}
	
	public static Set<String> getSysSet(String name) {
		return getSet(defaultType,name);
	}
	
	public static Map<String,String> getMap(String type, String name) {
		Map<String,Object> valMap = userProps.get(type);
		if(valMap==null) {
			return null;
		}
		Map<String,String> val =  (Map<String,String>) valMap.get(name);
		
		return val;
	}
	
	public static Map<String,String> getSysMap(String name) {
		return getMap(defaultType,name);
	}
	
	public static String[] getArray(String type, String name) {
		Map<String,Object> valMap = userProps.get(type);
		if(valMap==null) {
			return null;
		}
		Collection<String> val =  (Collection<String>) valMap.get(name);
		String[] arr = val.toArray(new String[0]);
		return arr;
	}
	
	public static String[] getSysArray(String name) {
		return getArray(defaultType,name);
	}
	
	private static Element tryAddType(String typeName) {
		
		Element config = document.getRootElement();
		List<Element> propertiesList = config.elements();
		Element tarProperties = null;
		for(Element properties:propertiesList) {
			if(properties.attributeValue("name").equals(typeName)) {
				tarProperties = properties;
				break;
			}
		}
		if(tarProperties==null) {
			tarProperties = config.addElement("properties");
			tarProperties.addAttribute("name", typeName);
		}
		
		return tarProperties;
	}
	

	public static void setSysString(String key,String value) throws Exception {
		setString(defaultType,key, value);
	}
	
	public static void setString(String typeName,String key,String value) throws Exception {
		
		Element tarProperties = tryAddType(typeName);
		List<Element> propertys  = tarProperties.elements();
		Element tarProperty = null;
		for(Element property:propertys) {
			if(property.attributeValue("name").equals(key)){
				tarProperty=property;
				break;
			}
		}
		if(tarProperty==null) {
			tarProperty = tarProperties.addElement("property");
			tarProperty.addAttribute("name", key);
			tarProperty.addAttribute("value", value);
		}
		
		XmlUtil.writeXml(document, confPath);
		freshInit();
	}
	
	public static void setSysSet(String key,Set setVal) throws Exception {
		setSet(defaultType, key, setVal);
	}
	
	public static void setSet(String typeName,String key,Set setVal) throws Exception {
		
		Element tarProperties = tryAddType(typeName);
		List<Element> propertys  = tarProperties.elements();
		Element tarProperty = null;
		for(Element property:propertys) {
			if(property.attributeValue("name").equals(key)){
				tarProperty=property;
				break;
			}
		}
		if(tarProperty==null) {
			tarProperty = tarProperties.addElement("property");
			tarProperty.addAttribute("name", key);
			tarProperty.addAttribute("type", "set");
		}
		
		for(Object val:setVal) {
			Element option = tarProperty.addElement("option");
			option.addAttribute("value", String.valueOf(val));
		}
		
		XmlUtil.writeXml(document, confPath);
		freshInit();
	}
	
	public static void setSysMap(String key,Map map) throws Exception {
		setMap(defaultType, key, map);
	}
	
	public static void setMap(String typeName,String key,Map map) throws Exception {
		
		Element tarProperties = tryAddType(typeName);
		List<Element> propertys  = tarProperties.elements();
		Element tarProperty = null;
		for(Element property:propertys) {
			if(property.attributeValue("name").equals(key)){
				tarProperty=property;
				break;
			}
		}
		if(tarProperty==null) {
			tarProperty = tarProperties.addElement("property");
			tarProperty.addAttribute("name", key);
			tarProperty.addAttribute("type", "map");
		}
		
		for(Object val:map.keySet()) {
			Element option = tarProperty.addElement("option");
			option.addAttribute("name", String.valueOf(val));
			option.addAttribute("value", String.valueOf(map.get(val)));
		}
		
		XmlUtil.writeXml(document, confPath);
		freshInit();
	}
	
}